\section{Git}
\bashinline{git push -u origin master}：添加远程库 

\bashinline{git remote add origin http://github.com/bleedingfight/test.git}：将本地文件推送给远程库 
\bashinline{git push -u origin +master}：强行推送
\subsection{git基础}
\begin{itemize}
	\item 添加账户
\begin{bash}
git config --global user.name "bleedingfight"
git config --global user.email "bleedingfight@126.com"
\end{bash}
\item 生成公钥
\begin{bash}
ssh-keygen -t rsa -C "bleedingfight@126.con"
\end{bash}
\item 不存在远程仓库时提交（主要用于在本地创建仓库提交到远程）
\begin{bash}
git init
git add README.md
git commit -m "first commit"
git remote add origin git@github.com:bleedingfight/cxx.git
git push -u origin master
\end{bash}
\item 存在远程仓库时提交（主要用于在远程创建仓库，然后clone到本地进行开发）
\begin{bash}
git remote add origin git@github.com:bleedingfight/cxx.git
git push -u origin master
\end{bash}
\end{itemize}
\subsection{分支管理}
\begin{itemize}
	\item 创建分支
\begin{bash}
# 在本地创建dev分支（需要先创建git仓库）
git checkout -b dev
\end{bash}
参数b表示创建并切换分支 相当于下面两条命令
\begin{bash}
git branch dev
git checkout dev
\end{bash}
\item 添加本地分支到远程不存在的分支,主要用于本地创建仓库后在直接提交到远程。
\begin{bash}
git push origin liushuai_local:liushuai_remote//将本地分支liushuai_local推送到远程分支liushuai_remote
git push origin liushuai10_dev:liushuai10_dev//将本地分支liushuai10_dev推送到远程作为liushuai10_dev分支。前提需要git remote add origin 仓库
\end{bash}
\item 删除分支
\begin{bash}
git branch -D dev # 删除本地分支
git checkout master # 切换到主分支
git merge dev # 融合dev分支
\end{bash}
返回当前分支的上一个版本
\begin{bash}
git reset --hard HEAD^

\end{bash}
\item 查看当前分支的日志信息：
\begin{bash}
git log 
git log --pretty=oneline # 更好的显示分支日志信息
\end{bash}
\item 查看远程仓库
\begin{bash}
git remote -v
origin https://github.com/bleedingfight/test.git (fetch)
origin https://github.com/bleedingfight/test.git (push)
\end{bash}
\item 获取远程仓库更新
\begin{bash}
git fetch origin master #从远程的origin仓库的master分支下载代码到本地的origin master
From https://github.com/com360/android-app
 * branch            master     -> FETCH_HEAD
su@SUCHANGLI /e/eoe_client/android-app (master)
\end{bash}
\item 强制更新远程仓库覆盖本地
\begin{bash}
git fetch --all
git reset --hard origin/master
git pull
\end{bash}
\item 比较本地仓库可远程仓库的区别
\begin{bash}
git log -p master.. origin/master
\end{bash}
把下载的代码合并到本地
\begin{bash}
git merge origin/master
\end{bash}
\item 获取远程最新版到本地
\begin{bash}
git fetch origin master:temp
\end{bash}
\item 比较本地和远程的区别
\begin{bash}
git diff temp
\end{bash}
\item 合并temp到master
\begin{bash}
git merge temp
\end{bash}
\item 删除远程分支note
\begin{bash}
git push origin :note
\end{bash}
\item 在某一条分支上后退后，想要前进到最新分支，这时候没有最新分支的提交信息，因此需要查看到最新提交的commit id，可以使用reflog查看。
\begin{bash}
git reflog # 用来记录你的每一次命令
\end{bash}
\begin{bash}
92ce393 (HEAD -> dev) HEAD@{0}: reset: moving to HEAD
92ce393 (HEAD -> dev) HEAD@{1}: reset: moving to HEAD^
c4662e4 (origin/dev) HEAD@{2}: commit: 添加py test文件
92ce393 (HEAD -> dev) HEAD@{3}: checkout: moving from master to dev
10674fd (origin/master, origin/HEAD, master) HEAD@{4}: commit: 添加测试代码
b91122a HEAD@{5}: clone: from https://github.com/bleedingfight/test.git
\end{bash}
然后可以看到py test提交的commit id就可以回到当前提交：
\begin{bash}
git reset --hard c4662e4
\end{bash}
\item 撤销修改，主要用于提交后发现错误，重新提交：
\begin{bash}
git add test.scala
git commit -m "update fiel"
git checkout -- test.scala
git commit -m "update file" # 修改提交
\end{bash}
\item 查看分支合并情况。
\begin{bash}
git log ---graph --pretty=oneline --abbrev-commit
\end{bash}
\end{itemize}
\section{标签管理}
发布一个版本时，我们通常先在版本库中打一个标签（tag），这样，就唯一确定了打标签时刻的版本。将来无论什么时候，取某个标签的版本，就是把那个打标签的时刻的历史版本取出来。所以，标签也是版本库的一个快照。Git的标签虽然是版本库的快照，但其实它就是指向某个commit的指针（跟分支很像对不对？但是分支可以移动，标签不能移动），所以，创建和删除标签都是瞬间完成的。Git有commit，为什么还要引入tag？
\begin{bash}
“请把上周一的那个版本打包发布，commit号是6a5819e...”

“一串乱七八糟的数字不好找！”

如果换一个办法：

“请把上周一的那个版本打包发布，版本号是v1.2”

“好的，按照tag v1.2查找commit就行！”
\end{bash}
所以，tag就是一个让人容易记住的有意义的名字，它跟某个commit绑在一起。
\begin{itemize}
	\item \bashinline{git tag v0.1}：创建标签。
	\item \bashinline{git tag}：查看标签。
	\item 默认标签是打在最新提交的commit上的。有时候，如果忘了打标签，比如，现在已经是周五了，但应该在周一打的标签没有打，怎么办？可以找到需要打标签的提交的commit id(git log --pretty=oneline --abbrev-commit)然后使用\bashinline{git tag v0.0 ec2a98c}打上标签。可以在\bashinline{git tag}上查看到按照标签字母排序排序的tag。
	\item \bashinline{git show v0.0} 查看v0.0 标签的信息。
	\item \bashinline{git tag -a v0.2 -m "添加新的语言支持" 5d45f876}：添加带有说明的分支信息。
	\item \bashinline{git tag -d v0.0}： 删除指定的tag v0.0。
	\item \bashinline{git push origin  v0.2}： 推送指定的tag v0.2到远程。
	\item \bashinline{git push origin --tags}：一次性推送所有标签到远程。
	\item 如果tag已经推送到远程了，需要删除远程的tag。需要首先在本地删除tag，然后删除远程tag。
		\begin{enumerate}
			\item \bashinline{git tag v0.2 -d}：删除本地tag。
			\item \bashinline{git push origin :refs/tags/v0.2}：删除远程的tag。
		\end{enumerate}
\end{itemize}
\subsection{常见问题}
公钥添加后依旧出错
\begin{bash}
sign_and_send_pubkey: signing failed: agent refused operation
Permission denied (publickey).
fatal: Could not read from remote repository.
\end{bash}
解决：ssh-add

git加入ssh公钥后依然需要密码推送！
\begin{bash}
git config --global credential.helper store
\end{bash}
融合分支的时候有时候分支拥有相同的文件，同时文件的内容不同。这时候合并的时候会出现类似："拒绝合并无关内容"。
这时候可以在merge的时候加上： \bashinline{allow-unrelated-histories}。例如合并全新的分支master和dev分支：\bashinline{git merge --allow-unrelated-histories dev}。这样冲突文件会被标注，手动解决冲突后即可提交。
